/**
* @Author: zou.yingbin
* @Create  : 2020/8/3 14:53
* @Modify  : 2020/8/3 14:53
 */

package main

import (
	"fmt"
	"github.com/beevik/etree"
	"github.com/golang/protobuf/proto"
	"github.com/kataras/iris/core/errors"
	"reflect"
	"strconv"
	"strings"
	MIProto "zyb/com_muchinfo_mtp_proto"
)

func stoUInt32(s string) uint32 {
	nValue, err := strconv.ParseInt(s, 10, 32)
	if err != nil {
		fmt.Println("parse int fail:", err)
		return 0
	}
	return uint32(nValue)
}

func stoUInt64(s string) uint64 {
	nValue, err := strconv.ParseInt(s, 10, 64)
	if err != nil {
		fmt.Println("parse int fail:", err)
		return 0
	}
	return uint64(nValue)
}

func getFieldValue(e *etree.Element, a interface{}, fieldName string)  {
	node := e.SelectElement(fieldName)
	if node == nil{
		return
	}

	v := reflect.ValueOf(a)

	switch a.(type) {
	case *uint32:
		v.Elem().Set(reflect.ValueOf(stoUInt32(node.Text())))
		//a = stoUInt32(node.Text())
	case *uint64:
		v.Elem().Set(reflect.ValueOf(stoUInt64(node.Text())))
		//a = stoUInt64(node.Text())
	}
}

func setFieldValue32(tag, v, fieldName string, fieldPtr *uint32)  {
	if strings.EqualFold(tag, fieldName) {
		*fieldPtr = stoUInt32(v)
	}
}
func setFieldValue64(tag, v, fieldName string, fieldPtr *uint64)  {
	if strings.EqualFold(tag, fieldName) {
		*fieldPtr = stoUInt64(v)
	}
}

func readMessage(nodeM *etree.Element,q *MIProto.RealtimeQuote) {
	childNodes := nodeM.ChildElements()
	for _, c := range childNodes{
		setFieldValue32(c.Tag, c.Text(), "MarketID", q.Header.MarketID)
		setFieldValue64(c.Tag, c.Text(), "Last", q.Last)
		setFieldValue64(c.Tag, c.Text(), "LastVolume", q.LastVolume)
		setFieldValue64(c.Tag, c.Text(), "TotalVolume", q.TotalVolume)
		setFieldValue64(c.Tag, c.Text(), "TotalHolderVolume", q.TotalHolderVolume)
		setFieldValue64(c.Tag, c.Text(), "ReckonPrice", q.ReckonPrice)
		setFieldValue64(c.Tag, c.Text(), "Open", q.Open)
		setFieldValue64(c.Tag, c.Text(), "High", q.High)
		setFieldValue64(c.Tag, c.Text(), "Low", q.Low)
		setFieldValue32(c.Tag, c.Text(), "QuoteType", q.QuoteType)
		setFieldValue32(c.Tag, c.Text(), "DecimalPlace", q.DecimalPlace)
	}
}

func ReadQuoteFromFile(fileName string) (*MIProto.RealtimeQuote, error) {
	fullName := "./goodsxml/" + fileName
	fmt.Println("read config from:", fullName)

	var err error = nil
	q := &MIProto.RealtimeQuote{
		Header: &MIProto.MessageHead{
			MarketID: proto.Uint32(15201),
			FunCode:  proto.Uint32(FID_RealtimeQuote),
		},
		Last:              proto.Uint64(0),
		LastVolume:        proto.Uint64(0),
		TotalVolume:       proto.Uint64(0),
		TotalHolderVolume: proto.Uint64(0),
		ReckonPrice:       proto.Uint64(0),
		Open:              proto.Uint64(0),
		High:              proto.Uint64(0),
		Low:               proto.Uint64(0),
		QuoteType:         proto.Uint32(15),
		DecimalPlace:      proto.Uint32(1),
		AskPriceArray:     make([]uint64, 0),
		BidPriceArray:     make([]uint64, 0),
		AskVolumeArray:    make([]uint64, 0),
		BidVolumeArray:    make([]uint64, 0),
		DateTime:          proto.String(""),
	}

	// do while
	for i := 0; i < 1; i++ {
		xmlDoc := etree.NewDocument()
		if xmlDoc == nil{
			err = errors.New("create etree doc fail.")
			break
		}

		err = xmlDoc.ReadFromFile(fullName)
		if err != nil {
			break
		}

		root := xmlDoc.SelectElements("message")
		if root == nil {
			err = errors.New("read message node fail.")
			break
		}

		//for _, e := range root {
		//	childNodes := e.ChildElements()
		//	for _, c := range childNodes{
		//		getFieldValue(c, q.Header.MarketID, "MarketID")
		//		getFieldValue(c, q.Last, "Last")
		//	}
		//}

		for _, e := range root {
			readMessage(e, q)
			//getFieldValue(e, q.Header.MarketID, "MarketID")
			//getFieldValue(e, q.Last, "Last")
			break
		}
	}

    return q, err
}